import { queryCheckCurrentPwd, queryCheckNewPwdIsUsed, querySavePassword } from '@/api/setApi'
import { quitLogin, getSystemLevel } from '@/utils/common'
import { DigestAuth } from '@/utils/encryption/digestAuth'
import { Message } from '@kedacom/react-next'
import { useContext, useEffect, useImperativeHandle, useState } from 'react'
import { alertModal } from '../Modal'
import { PasswordViewProps, UpdatePwdFormDataProps } from './interface'
import { AppContext } from '@/pages/App/context'
import { getErrorCodeMsg } from '@/plugins/axios/errorCode'
const useIndexHook = (props: PasswordViewProps, ref: React.Ref<unknown> | undefined) => {
	const AppData = useContext(AppContext)
	/**系统信息 */
	const systemInfo = AppData.system
	/**登录的用户的信息 */
	const userInfo = AppData.user
	const INPUT_WIDTH = 300
	// const DEFAULT_TIP = '长度10-16个字符、包含数字、大小写字母、符号"_""."'
	let strength = props.strength //'2'是中/强，3：'强‘
	/**
	 * 密码的强度（强中弱）规则（符合以上默认规则下，检验强度提示）
	 */
	/**秘密下密码最少要8位,机密等其他下密码最少10位 */
	const [isSecret, setIsSecret] = useState<boolean>(false)
	const defaultPwdRule10 = [
		{
			rule: {
				reg: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[._])[0-9a-zA-Z._]{10,16}$/,
				icon: 'strong',
				msg: '强',
			},
		},
		{
			rule: {
				reg: /(?!^([0-9]+|[a-zA-Z]+|[._]+)$)^[0-9a-zA-Z._?]{10,16}$/,
				icon: 'mid',
				msg: '中',
			},
		},
	]
	const defaultPwdRule8 = [
		{
			rule: {
				reg: /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[._])[0-9a-zA-Z._]{8,16}$/,
				icon: 'strong',
				msg: '强',
			},
		},
		{
			rule: {
				reg: /(?!^([0-9]+|[a-zA-Z]+|[._]+)$)^[0-9a-zA-Z._?]{8,16}$/,
				icon: 'mid',
				msg: '中',
			},
		},
	]
	const [pwdStrengthRules, setPwdStrengthRules] = useState<any[]>([])
	const [DEFAULT_TIP, setDefaultTip] = useState<string>('')
	useEffect(() => {
		let _isSecret = getSystemLevel(systemInfo?.systemSecurityLevel || 0) === 'secret'
		setIsSecret(_isSecret)
		let pwdRule = _isSecret ? defaultPwdRule8 : defaultPwdRule10
		setPwdStrengthRules(pwdRule)
		let min = _isSecret ? 8 : 10
		setDefaultTip(`长度${min}-16个字符、包含数字、大小写字母、符号"_""."`)
	}, [systemInfo])
	const defaultNewConfirmPwd = {
		newPwd: '',
		newPwdCheck: false,
		newPwdCheckIcon: '',
		newPwdCheckText: '',
		newPwdTip: '', //长度8-16个字符、包含数字、大小写字母、符号"_""."

		confirmPwd: '',
		confirmPwdCheck: false,
		confirmPwdCheckIcon: '',
		confirmPwdCheckText: '',
	}
	/**密碼组件默认值 */
	const defaultFormData = {
		currentPwd: '',
		currentPwdCheck: false, //true 检查结果正确 false检查结果错误
		currentPwdCheckIcon: '', //right 密码一致 error密码不一致
		currentPwdTip: '', //提示语
		...defaultNewConfirmPwd,
	}
	/**是否展示当前密码，默认展示 */
	const [formData, setFormData] = useState<UpdatePwdFormDataProps>({
		...defaultFormData,
	})
	/**
	 * 暴露组件的方法
	 */
	useImperativeHandle(ref, () => ({
		/**检查内容是否改变 */
		checkIsChanged: () => {
			return checkIsChanged()
		},
		/**保存数据 */
		saveData: () => {
			toSave()
		},
		/**获取表单数据 */
		getData: () => {
			return formData
		},
		/**校验密码强度,false不符合,true:符合密码强度 */
		checkPwdStrong: () => {
			return checkPwdStrong()
		},
	}))
	useEffect(() => {
		if (userInfo) {
			DigestAuth.username = (userInfo && userInfo.moid) || ''
			DigestAuth.realm = systemInfo.realmName || 'kedacom'
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [userInfo, systemInfo])
	useEffect(() => {
		props.onChange && props.onChange(formData)
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [formData])
	useEffect(() => {
		if (formData.confirmPwd) {
			//如果确认密码有值 要判断是否一致
			checkNewPwdConfirmPwdSame(formData.newPwd, formData.confirmPwd, 'confirmPwd')
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [formData.newPwd])
	const toSave = () => {
		let result = checkAllPwd()
		if (!result) {
			return false
		}
		let dataJson = {
			moid: userInfo.moid,
		}
		let newPwd = formData.newPwd
		let data = DigestAuth.makePassword(formData.currentPwd, newPwd)
		dataJson = {
			...dataJson,
			...data,
		}
		let m = Message.loading('loading')
		querySavePassword(dataJson)
			.then(() => {
				m.hide()
				alertModal({
					msg: '密码修改成功，请重新登录。',
					onOk: () => {
						quitLogin()
					},
				})
			})
			.catch(() => {
				m.hide()
			})
	}
	const checkIsChanged = () => {
		let isChanged = false //默认没有改变
		let hasVal = formData.currentPwd || formData.newPwd || formData.confirmPwd
		if (hasVal) {
			//有改动
			isChanged = true //内容改变了
		}
		return isChanged
	}
	/**校验新密码输入的密码强度 */
	// const checkPwdStrong = () => {
	// 	let newPwd = formData.newPwd
	// 	if (strength === 3) {
	// 		//密码需要为强
	// 		let rule = PWD_STRENGTH_RULES[0].rule
	// 		let reg = rule.reg
	// 		if (!reg.test(newPwd)) {
	// 			alertModal({
	// 				msg: '密码强度需设置为强',
	// 			})
	// 			return false
	// 		}
	// 	} else if (strength === 2) {
	// 		//密码需要为强/中
	// 		let strong = PWD_STRENGTH_RULES[0].rule //强
	// 		let strongReg = strong.reg
	// 		let mid = PWD_STRENGTH_RULES[1].rule //中
	// 		let midReg = mid.reg
	// 		if (!strongReg.test(newPwd) && !midReg.test(newPwd)) {
	// 			alertModal({
	// 				msg: '密码强度需设置为中或强',
	// 			})
	// 			return false
	// 		}
	// 	}
	// 	return true
	// }
	/**新密码失去焦点时，判断是否符合强度要求 */
	const checkPwdStrong = () => {
		let newPwd = formData.newPwd
		if (strength === 3) {
			//密码需要为强
			let rule = pwdStrengthRules[0].rule
			let reg = rule.reg
			if (!reg.test(newPwd)) {
				setFormData({
					...formData,
					newPwdCheck: false,
					newPwdCheckIcon: 'error',
					newPwdCheckText: '密码强度需设置为强',
					newPwdTip: '',
				})
				return false
			}
		} else if (strength === 2) {
			//密码需要为强/中
			let strong = pwdStrengthRules[0].rule //强
			let strongReg = strong.reg
			let mid = pwdStrengthRules[1].rule //中
			let midReg = mid.reg
			if (!strongReg.test(newPwd) && !midReg.test(newPwd)) {
				setFormData({
					...formData,
					newPwdCheck: false,
					newPwdCheckIcon: 'error',
					newPwdCheckText: '密码强度需设置为中或强',
					newPwdTip: '',
				})
				return false
			}
		}
		return true
	}
	/**校验新密码和重置密码输入 */
	const checkAllPwd = () => {
		if (!formData.currentPwdCheck) {
			alertModal({
				msg: '密码不一致，请重新输入',
			})
			return false
		}
		if (!formData.newPwdCheck) {
			if (formData.newPwd) {
				alertModal({
					msg: '新密码不能为空，请输入新密码。',
				})
				return false
			} else {
				alertModal({
					msg: '新密码不能为空，请输入新密码。',
				})
				return false
			}
		}
		if (!formData.confirmPwdCheck) {
			if (formData.confirmPwd !== formData.newPwd) {
				alertModal({
					msg: '两次输入密码不一致，请重新输入。',
				})
				return false
			}
		}
		// return checkPwdStrong()
		return true
	}
	/**
	 * 输入框改变时
	 * @param v 密码的值
	 * @param name 密码的键名
	 */
	const onInputChange = (v: string, name: string) => {
		if (name === 'currentPwd') {
			currentPwdChange(v, name)
		} else if (name === 'newPwd') {
			newPwdChange(v, name)
		} else {
			//确认密码改变时
			confirmPwdChange(v, name)
		}
	}

	/**
	 * 输入框聚焦时
	 * @param v 密码的值
	 * @param name 密码的键名
	 */
	const onInputFocus = (string: any, name: string) => {
		if (name === 'newPwd') {
			//新密码
			const showCurrentPwd = props.isShowCurrentPwd === false ? false : true
			const tip = showCurrentPwd ? (formData.currentPwdCheck ? DEFAULT_TIP : '') : DEFAULT_TIP
			setFormData({
				...formData,
				newPwdTip: tip,
			})
		}
		//聚焦到确认密码时 校验新密码的输入
		// if (name === 'confirmPwd') {
		// 	if (formData.currentPwdCheck) {
		// 		if (formData.newPwd === '') {
		// 			setFormData({
		// 				...formData,
		// 				newPwdCheck: false,
		// 				newPwdCheckIcon: 'error',
		// 				newPwdCheckText: '密码不得为空',
		// 			})
		// 		}
		// 	}
		// }
	}

	/**
	 * 当前密码改变时，隐藏后面的密码是否一致的提示，没有值时，清空后面的新密码和确认密码
	 * @param v 当前密码的值
	 * @param name 当前密码的键名
	 */
	const currentPwdChange = (v: string, name: string) => {
		if (!v) {
			resetAllPwd()
			return false
		}
		setFormData({
			...formData,
			currentPwdCheckIcon: '',
			[name]: v,
			currentPwdCheck: v ? formData.currentPwdCheck : false, //校验在无值的时候检验
		})
	}

	/**
	 * 新密码改变时
	 * @param v 新密码的值
	 * @param name 新密码的键名
	 */
	const newPwdChange = (v: string, name: string) => {
		let newPwdCheckIcon = 'error' ////根据检查结果做的图标提示
		let newPwdCheck = false //默认输入的新密码不符合规则
		let newPwdCheckText = '' //根据检查结果做的文字提示
		//如果清空了新密码，要更新新密码和确认密码的状态，自动清空确认密码的值
		if (!v) {
			resetNewConfirmPwd()
			return false
		}
		//如果有值，检验判断
		let min = isSecret ? 8 : 10
		if (v.length < min) {
			// newPwdCheckText = '长度至少为10位'
			newPwdCheckText = `长度至少为${min}位`
		} else {
			//判断是否满足
			for (let i = 0; i < pwdStrengthRules.length; i++) {
				let rule = pwdStrengthRules[i].rule
				let reg = rule.reg
				if (reg.test(v)) {
					//符合规则
					newPwdCheckIcon = rule.icon
					newPwdCheckText = rule.msg
					newPwdCheck = true
					break
				} else {
					//三种强度规则都不符合
					newPwdCheckIcon = 'error'
					newPwdCheckText = '密码不符合要求'
					newPwdCheck = false
				}
			}
		}
		/**输入的新密码是否和当前密码一样 */
		let isSameToCurrentPwd = formData.currentPwd && v && formData.currentPwd === v
		if (isSameToCurrentPwd) {
			newPwdCheckIcon = 'error'
			newPwdCheckText = '新旧密码不得相同'
			newPwdCheck = false
		}
		setFormData({
			...formData,
			newPwdCheckIcon,
			newPwdCheckText,
			newPwdCheck,
			[name]: v,
		})
	}
	/**
	 * 确认密码改变时
	 * @param v 输入的值
	 * @param name 键名
	 */
	const confirmPwdChange = (v: string, name: string) => {
		checkNewPwdConfirmPwdSame(formData.newPwd, v, name)
	}
	/**
	 * 判断新密码和确认密码是否一致
	 * @param newPwd 新密码
	 * @param confirmPwd 确认密码
	 * @param name 键名
	 */
	const checkNewPwdConfirmPwdSame = (newPwd: string, confirmPwd: string, name: string) => {
		let confirmPwdCheckIcon = 'error',
			confirmPwdCheckText = '密码不一致',
			confirmPwdCheck = false
		if (!newPwd && !confirmPwd) {
			confirmPwdCheckIcon = ''
			confirmPwdCheckText = ''
			confirmPwdCheck = false
		} else {
			if (newPwd === confirmPwd) {
				confirmPwdCheckIcon = 'right'
				confirmPwdCheckText = '密码一致'
				confirmPwdCheck = true
			}
		}
		setFormData({
			...formData,
			confirmPwdCheckIcon,
			confirmPwdCheckText,
			confirmPwdCheck,
			[name]: confirmPwd,
		})
	}
	/**
	 * 鼠标在当前密码失去焦点时 判断密码输入是否一致
	 * 如果不一致 新密码和确认密码禁止输入&&清空已输入的内容
	 * @param v 输入的值
	 * @param name 键名字
	 */
	const onInputBlur = (v: string, name: string) => {
		if (name === 'currentPwd') {
			onCurrentPwdBlur(v)
		}
		if (name === 'newPwd') {
			onNewPwdBlur(v)
		}
	}
	/**
	 * 当前密码失去焦点时 判断输入的密码是否是当前用户的密码
	 * @param v 输入值
	 * @returns
	 */
	const onCurrentPwdBlur = (v: string) => {
		if (!v) {
			//当前密码有值时接口校验输入是否正确
			return false
		}
		if (v) {
			let dataJson = {
				moid: userInfo ? userInfo.moid : '',
			}
			console.log(DigestAuth, 'DigestAuth')
			let data = DigestAuth.makePassword(v, v)
			dataJson = {
				...dataJson,
				...data,
			}

			queryCheckCurrentPwd(dataJson)
				.then(() => {
					setFormData({
						...formData,
						currentPwdCheck: true,
						currentPwdCheckIcon: 'right', //失去焦点时如果没有value，不展示密码是否一致的提示
					})
				})
				.catch(() => {
					setFormData({
						...formData,
						currentPwdCheckIcon: 'error',
						...defaultNewConfirmPwd,
					})
				})
		}
	}
	/**
	 * 新密码失去焦点时，默认会走接口判断输入得是否是历史密码。
	 * 个人设置的修改密码页面目前使用的是该默认方式，如果需求更改，可以修改掉这里
	 */
	const onNewPwdBlur = (v: string) => {
		if (formData.newPwdCheck) {
			/**校验是否符合强度，不符合则并给与错误提示 */
			let isFit = checkPwdStrong()
			if (isFit) {
				//符合强度后，检验是否是历史密码
				defaultCheckUsedOnNewPwdBlur(v)
			}
		}
	}
	/**检查新密码是否是历史密码 */
	const checkIsUsed = () => {
		if (props.isCheckNewPwdUsed !== false) {
			let newPwdTip = formData.newPwdCheck ? '' : formData.newPwdTip
			let dataJson = {
				moid: userInfo ? userInfo.moid : '',
			}
			let newPwd = formData.newPwd
			let data = DigestAuth.makePassword(formData.currentPwd, newPwd)
			dataJson = {
				...dataJson,
				...data,
			}
			queryCheckNewPwdIsUsed(dataJson)
				.then(() => {
					//密码没有使用过
				})
				.catch((res) => {
					let code = res.errorCode
					let msg = getErrorCodeMsg(code)
					//110015状态码是 该密码已使用过
					let isUsed = code === 110015
					if (isUsed) {
						//已使用的错误，红色文字提示
						setFormData({
							...formData,
							newPwdTip,
							newPwdCheck: false,
							newPwdCheckIcon: 'error',
							newPwdCheckText: '密码已使用',
						})
					} else {
						//其他类型的错误，弹窗提示
						alertModal({
							msg,
						})
					}
				})
		}
	}
	const defaultCheckUsedOnNewPwdBlur = (v: string) => {
		if (v) {
			// 新密码和当前密码输入不一样后，判断是否是历史密码
			if (props.isShowCurrentPwd && formData.currentPwd !== v) {
				checkIsUsed()
			} else if (!props.isShowCurrentPwd) {
				//没有当前密码，则新密码失去焦点时，都要判断是否是历史密码
				checkIsUsed()
			}
		}
	}
	/**
	 * 重置新密码和确认密码
	 */
	const resetNewConfirmPwd = () => {
		setFormData({
			...formData,
			...defaultNewConfirmPwd,
		})
	}
	/**
	 * 重置确认密码
	 */
	const resetAllPwd = () => {
		setFormData({
			...defaultFormData,
		})
	}
	return {
		INPUT_WIDTH,
		formData,
		onInputChange,
		onInputBlur,
		onInputFocus,
	}
}
export default useIndexHook
